## Johnson's upper bound for binary codes

from PyM import *

def ub_johnson(n,d,w=''):
    if isinstance(w,int):
        h = floor((d+1)/2)
        b = 1
        if h <= w:
            for i in range(w-h,-1,-1):
                b = floor(b*(n-i)/(w-i))
            return b
        else:
            return 1
    if d%2==0:
        n = n-1; d=d-1
    t = floor(d/2)
    x = binom(n,t+1)-binom(d,t)*ub_johnson(n,d,d)
    x = x/floor(n/(t+1))
    for i in range(t+1):
        x += binom(n,i)
    return floor(2**n/x)

show(ub_johnson(13,5,5))

show(ub_johnson(13,5))

show([ub_johnson(n,3) for n in range(5,17)])

show([ub_johnson(n,5) for n in range(5,17)])

show([ub_johnson(n,7) for n in range(7,17)])